var crypto = require('crypto');
var MongoDB = require('mongodb').Db;
var Server = require('mongodb').Server;
var moment = require('moment');


/*
 ESTABLISH DATABASE CONNECTION
 */

var dbName = process.env.DB_NAME || 'node-login';
var dbHost = process.env.DB_HOST || 'localhost'
var dbPort = process.env.DB_PORT || 27017;


var accountRoles = [
    {role: 1, role_name: '管理员'},
    {role: 2, role_name: '普通用户'},
    {role: 3, role_name: '特殊用户'},
];

var db = new MongoDB(dbName, new Server(dbHost, dbPort, {auto_reconnect: true}), {w: 1});
db.open(function (e, d) {
    if (e) {
        console.log(e);
    } else {
        if (process.env.NODE_ENV == 'live') {
            db.authenticate(process.env.DB_USER, process.env.DB_PASS, function (e, res) {
                if (e) {
                    console.log('mongo :: error: not authenticated', e);
                }
                else {
                    console.log('mongo :: authenticated and connected to database :: "' + dbName + '"');
                }
            });
        } else {
            console.log('mongo :: connected to database :: "' + dbName + '"');
        }
    }
});

var accounts = db.collection('accounts');


/* login validation methods */

exports.autoLogin = function (user, pass, callback) {
    accounts.findOne({user: user}, function (e, o) {
        if (o) {
            o.pass == pass ? callback(o) : callback(null);
        } else {
            callback(null);
        }
    });
};

//检查用户是否为管理员
exports.checkUserRole = function (user, callback) {
    var res = {};
    console.log('--- user ---' + user);
    accounts.findOne({user: user}, function (err, result) {
        console.log('--- checkUserRole err --- ' + err);
        if (result['role'] == 1) {//检查成功， 用户角色为管理员
            res['id'] = 1;
            res['msg'] = '检查成功, 管理员';
            callback(res);
        } else if (result['role'] === 2) {
            res['id'] = 2; //检查失败
            res['msg'] = '检查失败，普通用户'; //
            callback(res);
        } else {
            res['id'] = 3;
            res['msg'] = '特殊用户'; //特殊用户，可以申请特殊时间段预约，但是不能进入用户管理和预约管理页面
            callback(res);
        }
    });
};

exports.manualLogin = function (user, pass, callback) {
    var result = {};
    accounts.findOne({user: user}, function (err, res) {
        if (res == null) {
            result['id'] = 2;
            result['msg'] = '账号不存在';
            callback(result);
        } else {
            if (res['role'] == 1) { //如果用户是管理员
                res['status'] = 2;
            }

            if (res['status'] == 1) { //1 - 申请中 2-申请成功 3-申请失败
                result['id'] = 2;
                result['msg'] = '登录失败，该账号处于申请状态';
                callback(result);
            } else if (res['status'] == 3) {
                result['id'] = 2;
                result['msg'] = '登录失败，该账号申请被拒绝';
                callback(result);
            } else {
                validatePassword(pass, res.pass, function (err, res2) {
                    if (res2) {
                        result['id'] = 1;
                        result['msg'] = '登录成功';
                        result['data'] = res;
                        callback(result);
                        // callback(null, o);
                    } else {
                        result['id'] = 2;
                        result['msg'] = '密码错误';
                        callback(result);
                    }
                });
            }

        }
    });
};

//保存图片
function saveImage(myBase64, imgPath) {
    // Remember to execute this after the onDeviceReady event

    // var contentType = "image/png";
    // var folderpath = cordova.file.externalRootDirectory;
    // var filename = "ourcodeworld.jpeg";

    // savebase64AsImageFile('.', filename, myBase64, contentType);
    // B2F.savebase64AsImageFile('.', filename, myBase64);

    var base64Data = myBase64.replace(/^data:image\/jpeg;base64,/, "");

    require("fs").writeFile(imgPath, base64Data, 'base64', function (err) {
        console.log(err);
    });

}
/* record insertion, update & deletion methods */
exports.addNewAccount = function (newData, callback) {
    var res = {};
    newData['role'] = 2; //默认是普通用户, 管理员和特殊用户只能通过手动添加
    newData['status'] = 1; //状态， 账号申请中
    accounts.findOne({user: newData['user']}, function (e, o) {
        if (o) {
            res['id'] = 2;
            res['msg'] = '用户名已存在';
            callback(res);
        } else {
            accounts.findOne({"contact-email": newData['contact-email']}, function (e, o) {
                if (o) {
                    res['id'] = 2;
                    res['msg'] = '邮箱已存在';
                    callback(res);
                } else {
                    saltAndHash(newData['pass'], function (hash) {
                        newData.pass = hash;
                        newData.date = moment().unix();

                        // if (newData['business-license'] != '') {
                        //     var imgPath = "./images/license/" + newData['user'] + ".jpeg";
                        //     saveImage(newData['business-license'], imgPath);
                        //     newData['business-license'] = imgPath;
                        // }
                        //
                        // if (newData['organization-code'] != '') {
                        //     var imgPath = "./images/code/" + newData['user'] + ".jpeg";
                        //     saveImage(newData['organization-code'], imgPath);
                        //     newData['organization-code'] = imgPath;
                        // }

                        accounts.insert(newData, {safe: true}, function (e, o) {
                            if (!e) {
                                res['id'] = 1;
                                res['msg'] = '账号申请成功, 请等待管理员审核';
                                callback(res);
                            } else {
                                res['id'] = 1;
                                res['msg'] = '账号申请失败, 请等待管理员审核';
                                callback(res);
                            }
                        });
                    });
                }
            });
        }
    });
};

exports.updateAccountStatus = function (statusData, callback) {
    console.log(' --- updateAccountStatus ---');
    var result = {};
    accounts.update({"_id": getObjectId(statusData.id)}, {$set: {'status': statusData.status}}, function (err, res) {
        if (err) {
            result['id'] = 2;
            result['msg'] = '账号状态更新失败';
            callback(result);
        } else {
            result['id'] = 1;
            result['msg'] = '账号状态更新成功';
            callback(result);
        }
    });

};

function updateAccountInfo(newData, o, res, callback) {
    accounts.update({_id: getObjectId(newData.id)}, {'$set': newData}, function (e) {
        if (e) {
            res['id'] = 2;
            res['msg'] = '账号信息修改失败';
            callback(res);
        } else {
            res['id'] = 1;
            res['data'] = o;
            res['msg'] = '账号信息修改成功';
            callback(res);
        }
    });
}

//更新用户信息
exports.updateAccount = function (newData, pass, callback) {
    var res = {};
    accounts.findOne({_id: getObjectId(newData.id)}, function (e, o) {
        if (!o) {
            res['id'] = 2;
            res['msg'] = '账号信息修改失败';
            callback(res);
        } else {
            if (pass.trim() === '') { //如果用户不修改密码
                console.log('pass null');
                updateAccountInfo(newData, o, res, callback);
            } else {
                console.log('pass not null');
                saltAndHash(pass, function (hash) {
                    newData['pass'] = hash;
                    updateAccountInfo(newData, o, res, callback);
                });
            }

        }
    });


    // //检查用户名和密码是否已经存在
    // if(newData['user'] === undefined)
    //     newData['user'] = ''; //如果是更新用户信息， 则不更新用户名
    //
    // if(newData['contact-email'] === undefined)
    //     newData['contact-email'] = ''; //如果是更新用户信息， 则不更新联系邮箱
    //
    // accounts.findOne({user: newData['user']}, function (e, o) {
    //     console.log(' --- user --- ', newData['user']);
    //     if (o) {
    //         res['id'] = 2;
    //         res['msg'] = '用户名已存在';
    //         callback(res);
    //     } else {
    //         accounts.findOne({"contact-email": newData['contact-email']}, function (e, o) {
    //             if (o) {
    //                 res['id'] = 2;
    //                 res['msg'] = '邮箱已存在';
    //                 callback(res);
    //             } else {
    //                 if (pass.trim() === '') { //如果用户不修改密码
    //                     console.log('pass null');
    //                     accounts.update({_id: getObjectId(newData.id)}, {'$set': newData}, function (e) {
    //                         if (e) {
    //                             res['id'] = 2;
    //                             res['msg'] = '账号信息修改失败';
    //                             callback(res);
    //                         } else {
    //                             res['id'] = 1;
    //                             res['data'] = accounts.findOne({user: newData._id});
    //                             res['msg'] = '账号信息修改成功';
    //                             callback(res);
    //                         }
    //                     });
    //                 } else {
    //                     console.log('pass not null');
    //                     saltAndHash(pass, function (hash) {
    //                         newData['pass'] = hash;
    //                         accounts.update({_id: getObjectId(newData.id)}, {'$set': newData}, function (e) {
    //                             if (e) {
    //                                 res['id'] = 2;
    //                                 res['msg'] = '账号信息修改失败';
    //                                 callback(res);
    //                             } else {
    //                                 res['id'] = 1;
    //                                 res['data'] = accounts.findOne({user: newData._id});
    //                                 res['msg'] = '账号信息修改成功';
    //                                 callback(res);
    //                             }
    //                         });
    //                     });
    //
    //                 }
    //             }
    //         })
    //     }
// )
// ;

// accounts.findOne({_id: getObjectId(newData.id)}, function (e, o) {
//     o['user'] = newData['user'];
//     // o['inc-name'] = newData['inc-name'];
//     // o['inc-address'] = newData['inc-address'];
//     o['contact-name'] = newData['contact-name'];
//     o['contact-phone'] = newData['contact-phone'];
//     o['contact-email'] = newData['contact-email'];
//     // o['contact-tel'] = newData['contact-tel'];
//     o['contact-postion'] = newData['contact-postion'];
//     // o['inc-number'] = newData['inc-number'];
//     // o['inc-industry'] = newData['inc-industry'];
//     // o['inc-property'] = newData['inc-property'];
//     // o['business-license'] = newData['business-license'];
//     // o['organization-code'] = newData['organization-code'];
//
//     console.log(' --- typeof pass ----', typeof newData['pass']);
//     if (newData['pass'].trim() === '') {
//         console.log('pass null');
//         accounts.update({_id: getObjectId(newData.id)}, o, function (e) {
//             if (e) {
//                 result['id'] = 2;
//                 result['msg'] = '账号信息修改失败';
//                 callback(result);
//             } else {
//                 result['id'] = 1;
//                 result['data'] = o;
//                 result['msg'] = '账号信息修改成功';
//                 callback(result);
//             }
//         });
//     } else {
//         console.log('pass not null');
//         saltAndHash(newData['pass'], function (hash) {
//             o['pass'] = hash;
//             accounts.update({_id: getObjectId(newData.id)}, o, function (e) {
//                 if (e) {
//                     result['id'] = 2;
//                     result['msg'] = '账号信息修改失败';
//                     callback(result);
//                 } else {
//                     result['id'] = 1;
//                     result['data'] = o;
//                     result['msg'] = '账号信息修改成功';
//                     callback(result);
//                 }
//             });
//             // accounts.save(o, {safe: true}, function (e) {
//             //     if (e) {
//             //         result['id'] = 2;
//             //         result['msg'] = '账号信息修改失败';
//             //         callback(result);
//             //     } else {
//             //         result['id'] = 1;
//             //         result['data'] = o;
//             //         result['msg'] = '账号信息修改成功';
//             //         callback(result);
//             //     }
//             //
//             // });
//         });
//     }
// });
}

//更新密码
exports.updatePassword = function (email, newPass, callback) {
    accounts.findOne({"contact-email": email}, function (e, o) {
        if (e) {
            callback(e, null);
        } else {
            saltAndHash(newPass, function (hash) {
                o.pass = hash;
                accounts.save(o, {safe: true}, callback);
            });
        }
    });
};

/* account lookup methods */

exports.deleteAccount = function (id, callback) {
    var result = {};
    accounts.remove({_id: getObjectId(id)}, function (err, res) {
        if (err) {
            result['id'] = 2;
            result['msg'] = '账号删除失败';
        } else {
            result['id'] = 1;
            result['msg'] = '账号删除成功';
        }
        callback(result);
    });
};

exports.getAccountByEmail = function (email, callback) {
    accounts.findOne({"contact-email": email}, function (e, o) {
        callback(o);
    });
};

exports.validateResetLink = function (email, passHash, callback) {
    accounts.findOne({"contact-email": email, pass: passHash}, function (e, o) {
        callback(o ? 'ok' : null);
    });
};

//获取用户信息
exports.getRecords = function (_id, callback) {
    var result = {};
    // accounts.findOne({_id: getObjectId(id)}, function (err, res) {
    accounts.findOne({_id: getObjectId(_id)}, function (err, res) {
        if (err) {
            result['id'] = 2;
            result['data'] = null;
            result['msg'] = '获取账号信息失败';
            callback(result);
        } else {
            result['id'] = 1;
            result['data'] = res;
            result['msg'] = '获取账号信息成功';
            callback(result);
        }
    });
};

//获取用户列表
exports.getAllRecords = function (query, callback) {
    var result = {};
    //返回指定字段
    // '_id', 'user', 'contact-name', 'contact-phone', 'contact-email', 'date'
    accounts.find(query, {
        '_id': 1,
        'user': 1,
        'contact-name': 1,
        'contact-phone': 1,
        'contact-email': 1,
        'inc-name': 1,
        'date': 1,
        'role': 1,
        'status': 1
    }).toArray(
        function (e, res) {
            console.log(' get all account err' + e);
            console.log(' get all account res' + res);
            // if (e)
            //     callback(e)
            // else
            //     callback(null, res)
            if (e) {
                result['id'] = 2;
                result['data'] = null;
                result['msg'] = '获取账号列表失败';
                callback(result);
            } else {
                result['id'] = 1;
                if (res.length == 0)
                    result['data'] = null;
                else
                    result['data'] = res;
                result['msg'] = '获取账号列表成功';
                callback(result);
            }

        });
};

exports.delAllRecords = function (callback) {
    accounts.remove({}, callback); // reset accounts collection for testing //
};

/* private encryption & validation methods */

var generateSalt = function () {
    var set = '0123456789abcdefghijklmnopqurstuvwxyzABCDEFGHIJKLMNOPQURSTUVWXYZ';
    var salt = '';
    for (var i = 0; i < 10; i++) {
        var p = Math.floor(Math.random() * set.length);
        salt += set[p];
    }
    return salt;
};

var md5 = function (str) {
    return crypto.createHash('md5').update(str).digest('hex');
};

var saltAndHash = function (pass, callback) {
    var salt = generateSalt();
    callback(salt + md5(pass + salt));
};

var validatePassword = function (plainPass, hashedPass, callback) {
    var salt = hashedPass.substr(0, 10);
    var validHash = salt + md5(plainPass + salt);
    callback(null, hashedPass === validHash);
};

var getObjectId = function (id) {
    return new require('mongodb').ObjectID(id);
};

var findById = function (id, callback) {
    accounts.findOne({_id: getObjectId(id)},
        function (e, res) {
            if (e) callback(e);
            else callback(null, res)
        });
};

var findByMultipleFields = function (a, callback) {
    accounts.find({$or: a}).toArray(
        function (e, results) {
            if (e) callback(e);
            else callback(null, results)
        });
};
